package com.lange.autocode.sysManager;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import cn.net.autocode.core.bean.ResultT;
import cn.net.autocode.core.utils.UserThreadLocalUtils;
import cn.net.autocode.dbManager.Dao;
import cn.net.autocode.dbManager.IdWorker;
import cn.net.autocode.dbManager.SqlWrapper;
import cn.net.autocode.dbManager.SqlWrapperBuilder;
import cn.net.autocode.files.excel.ExcelTools;
import cn.net.autocode.platform.busiModel.TreeBusiModel;
import cn.net.autocode.platform.factory.AutoCodeQueryFactory;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.lange.autocode.sysManager.service.OrganServ;
import com.lange.autocode.sysManager.service.UserServ;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/sysManager/sysOrgan")
public class SysOrgan {
    private final Dao dao;

    private final OrganServ organServ;
    private final UserServ userServ;
    private final TreeBusiModel treeBusiModel;

    public SysOrgan(Dao dao, OrganServ organServ, UserServ userServ, TreeBusiModel treeBusiModel) {
        this.dao = dao;
        this.organServ = organServ;
        this.userServ = userServ;
        this.treeBusiModel = treeBusiModel;
    }

    @RequestMapping("detail")
    public ResultT detail(@RequestBody JSONObject param){
        String id = param.getString("id");
        if (id == null || id.isBlank()) {
            JSONObject organ = dao.queryJSON("select t1.*,t2.fullname manager_label,t3.fullname admin_label from sys_organ t1 left join sys_users t2 on t1.manager=t2.username left join sys_users t3 on t1.org_manager=t3.username where t1.code=?",UserThreadLocalUtils.getOrgCode());
            return ResultT.success(organ);
        }else{
            JSONObject organ = dao.queryJSON("select t1.*,t2.fullname manager_label,t3.fullname admin_label from sys_organ t1 left join sys_users t2 on t1.manager=t2.username left join sys_users t3 on t1.org_manager=t3.username where t1.id=?",id);
            return ResultT.success(organ);
        }

    }

    @RequestMapping("save")
    public ResultT save(@RequestBody JSONObject data){
        if(StrUtil.isBlank(data.getString("id"))){
            //设置org_level
            if(StrUtil.isBlank(data.getString("parentId"))){
                data.put("orgLevel",1);
            }else{
                int parentLevel = dao.queryValue("select org_level from sys_organ where id=?",Integer.class,data.getString("parentId"));
                data.put("orgLevel",parentLevel+1);
            }

            data.put("id", IdWorker.ulid());
            int count = dao.queryValue("select count(*) from sys_organ where code=?",Integer.class,data.getString("code"));
            if(count>0){
                return ResultT.fail(data.getString("code")+"已存在，不能重复添加");
            }
            JSONArray area = data.getJSONArray("area");
            if(area!=null && area.size()==3){
                data.put("province",area.getString(0));
                data.put("city",area.getString(1));
                data.put("county",area.getString(2));
            }
            dao.createJSON(data,"sys_organ");
        }
        return ResultT.success(data);

    }


    @RequestMapping("update/{fieldName}")
    public ResultT update(@PathVariable("fieldName") String fieldName, @RequestBody JSONObject data){
        return organServ.update(fieldName,data);
    }


    @RequestMapping("queryNotExistsUser")
    public ResultT queryNotExistsUser(@RequestBody JSONObject param){
        JSONObject pagingData = param.getJSONObject("pagingData");
        JSONObject operData = param.getJSONObject("operData");
        if(StrUtil.isBlank(operData.getString("orgCode"))){
            operData.put("orgCode", UserThreadLocalUtils.getOrgCode());
        }

        SqlWrapperBuilder swb = new SqlWrapperBuilder("sys_users t1");
        swb.where("not exists(select 1 from sys_organ_users t2 where t1.username=t2.username and t2.org_code=?)",operData.getString("orgCode"));
        swb.like("phone",operData.getString("phone"));
        swb.like("email",operData.getString("email"));
        swb.like("fullname",operData.getString("fullname"));
        if(StrUtil.isNotBlank(operData.getString("userName"))){
            swb.like("username",operData.getString("userName").toUpperCase());
        }

        SqlWrapper countSqlWrapper = swb.countSqlWrapper();
        dao.pageInfo(pagingData,countSqlWrapper.getSql(),countSqlWrapper.getParams().toArray());
        SqlWrapper sqlWrapper = swb.sqlWrapper();
        JSONArray data = dao.queryJSONArray(sqlWrapper.getSql(),sqlWrapper.getParams().toArray());

        JSONObject res = new JSONObject();
        res.put("pagingData",pagingData);
        res.put("data",data);
        return ResultT.success(res);
    }

    @RequestMapping("selectAddOrganUser")
    @Transactional
    public ResultT selectAddOrganUser(@RequestBody JSONArray array){
        if(array==null || array.isEmpty()){
            return ResultT.success();
        }
        String orgCode = array.getJSONObject(0).getString("orgCode");
        if (StrUtil.isBlank(orgCode)){
            orgCode = UserThreadLocalUtils.getOrgCode();
        }

        //获取默认角色
        List<String> defaultRole = AutoCodeQueryFactory.queryListValue("platformRole.defaultRole", Map.of("orgCode",orgCode));

        for(int i=0;i<array.size();i++){
            JSONObject json = array.getJSONObject(i);
            dao.executeUpdate("insert into sys_organ_users(id,username,org_code) values(?,?,?)",IdWorker.ulid(),json.getString("username"),orgCode);
            for(String roleId:defaultRole){
                dao.executeUpdate("insert into sys_role_users(id,role_id,username,org_code) values(?,?,?,?)",IdWorker.ulid(),roleId,json.getString("username"),orgCode);
            }
        }
        return ResultT.success();
    }

    @RequestMapping("delOrganUsers")
    @Transactional
    public ResultT delOrganUsers(@RequestBody JSONArray array){
        List<String> ids = new ArrayList<>();
        for(int i=0;i<array.size();i++){
            JSONObject json = array.getJSONObject(i);
            ids.add(json.getString("id"));
        }
        JSONArray deleteUsers = dao.queryJSONArray("select * from sys_organ_users where id in (?)",ids);
        for(int i=0;i<deleteUsers.size();i++){
            JSONObject orgUser = deleteUsers.getJSONObject(i);
            String orgCode = orgUser.getString("orgCode");
            String username = orgUser.getString("username");
            String id = orgUser.getString("id");
            dao.executeUpdate("delete from sys_role_users where org_code=? and username=?",orgCode,username);
            dao.executeUpdate("delete from sys_department_user as t1 where exists(select 1 from sys_departments t2 where t1.dept_id=t2.id and t2.org_code=?) and t1.username=?",orgCode,username);
            dao.executeUpdate("delete from sys_organ_users where id=?",id);
        }

        return ResultT.success();
    }

    @RequestMapping("addOrganUser")
    @Transactional
    public ResultT addOrganUser(@RequestBody JSONObject param){
        ResultT resultT = userServ.addUser(param);
        if(resultT.getCode()==0){
            return resultT;
        }
        JSONObject user = resultT.JSONObjectData();

        String orgCode = UserThreadLocalUtils.getOrgCode();
        //查询默认角色
        List<String> defaultRole = AutoCodeQueryFactory.queryListValue("platformRole.defaultRole", Map.of("orgCode",orgCode));

        String username=user.getString("username");
        String organUserId = IdWorker.ulid();

        //获取职务信息
        String jobTitle = param.getString("jobTitle");
        if(StrUtil.isBlank(jobTitle)){
            jobTitle = "ybyg";
        }

        dao.executeUpdate("insert into sys_organ_users(id,username,job_title,org_code) values(?,?,?,?)",organUserId,username,jobTitle,orgCode);
        for(String roleId:defaultRole){
            dao.executeUpdate("insert into sys_role_users(id,role_id,username,org_code) values(?,?,?,?)",IdWorker.ulid(),roleId,username,orgCode);
        }

        user.put("orgCode",orgCode);
        user.put("id",organUserId);
        return ResultT.success(user);
    }

    @RequestMapping("updateOrganUser")
    @Transactional
    public ResultT upateOrganUser(@RequestBody JSONObject param){
        param.remove("status");
        param.remove("id");
        dao.updateJSON(param,"sys_users","username");

        //更改职务级别
        String jobTitle = param.getString("jobTitle");
        String orgCode = param.getString("orgCode");
        String username = param.getString("username");
        dao.executeUpdate("update sys_organ_users set job_title=? where org_code=? and username=?",jobTitle,orgCode,username);

        return ResultT.success(param);
    }

    @RequestMapping("importOrganUser")
    @Transactional
    public ResultT importOrganUser(@RequestParam MultipartFile file) throws IOException {
        String orgCode = UserThreadLocalUtils.getOrgCode();

        //查询默认角色
        List<String> defaultRole = AutoCodeQueryFactory.queryListValue("platformRole.defaultRole", Map.of("orgCode",orgCode));

        //解析excel数据
        JSONArray array = ExcelTools.readExcel(file.getInputStream());
        //标题：用户名、用户全名、邮箱、电话
        Map<Integer,String> map = new HashMap<>();
        JSONArray titles = array.getJSONArray(0);
        for(int i=0;i<titles.size();i++){
            JSONObject title = titles.getJSONObject(i);
            String value = title.getString("value");
            if(value!=null){
                value=value.trim();
            }
            int columnIndex = title.getInteger("columnIndex");
            if("用户名".equals(value)){
                map.put(columnIndex,"username");
            }

            if("用户全名".equals(value)){
                map.put(columnIndex,"fullname");
            }

            if("邮箱".equals(value)){
                map.put(columnIndex,"email");
            }

            if("电话".equals(value)){
                map.put(columnIndex,"phone");
            }
        }


        for(int i=1;i<array.size();i++){
            JSONObject data = new JSONObject();
            JSONArray row = array.getJSONArray(i);
            for(int j=0;j<row.size();j++){
                JSONObject cell = row.getJSONObject(j);
                int columnIndex = cell.getInteger("columnIndex");
                if (map.containsKey(columnIndex)){
                    String value = cell.getString("value");
                    if (value!=null && !value.isBlank()){
                        data.put(map.get(columnIndex),value.trim());
                    }
                }
            }

            if (data.getString("username")==null){
                throw new RuntimeException("用户名不能为空！");
            }

            if (data.getString("fullname")==null){
                throw new RuntimeException("用户全名不能为空！");
            }

            //判断用户名是否存在
            int exists=dao.queryValue("select count(*) from sys_users where username=?", Integer.class,data.getString("username"));
            if(exists>0){
                throw new RuntimeException("用户名"+data.getString("username")+"已经存在！");
            }

            //邮箱、手机号格式验证
            if(!StrUtil.isBlank(data.getString("email"))){
                if(!Validator.isEmail(data.getString("email"))){
                    throw new RuntimeException(data.getString("email")+"邮箱地址无效！");
                }
                int emailExists = dao.queryValue("select count(*) from sys_users where email=?",Integer.class,data.getString("email"));
                if (emailExists>0){
                    throw new RuntimeException("邮箱地址"+data.getString("email")+"已存在!");
                }
            }

            if(!StrUtil.isBlank(data.getString("phone"))){
                if(!Validator.isMobile(data.getString("phone"))){
                    throw new RuntimeException(data.getString("phone")+"手机号格式错误！");
                }
                int phoneExists = dao.queryValue("select count(*) from sys_users where phone=?",Integer.class,data.getString("phone"));
                if (phoneExists>0){
                    throw new RuntimeException("手机号"+data.getString("phone")+"已存在!");
                }
            }

            dao.executeUpdate("insert into sys_users(id,username,fullname,email,phone) values(?,?,?,?,?)",IdWorker.ulid(),data.getString("username"),data.getString("fullname"),data.getString("email"),data.getString("phone"));

            dao.executeUpdate("insert into sys_organ_users(id,username,org_code) values(?,?,?)",IdWorker.ulid(),data.getString("username"),orgCode);
            for(String roleId:defaultRole){
                dao.executeUpdate("insert into sys_role_users(id,role_id,username,org_code) values(?,?,?,?)",IdWorker.ulid(),roleId,data.getString("username"),orgCode);
            }
        }

        return ResultT.success();
    }

    @RequestMapping("nodeDrop")
    @Transactional
    public ResultT nodeDrop(@RequestBody JSONObject param){
        JSONObject  draggingNode = param.getJSONObject("draggingNode");
        JSONObject  dropNode = param.getJSONObject("dropNode");
        String dropType = param.getString("dropType");
        String rs = treeBusiModel.nodeDrop(draggingNode,dropNode,dropType,"sys_organ");
        if (rs.equals("success")){
            return ResultT.success();
        }else{
            return ResultT.fail(rs);
        }
    }

}
